#ifndef __PY_DICT_MAP_HH__
#define __PY_DICT_MAP_HH__

#include <vector>
#include <map>
#include <sstream>
using namespace std;
#include <misc/error.h>

template <class K, class V>
class DictMap : private map<K, V>
{
public:
  size_t size() const;
  bool has_key(const K& k) const;  
  void remove(const K& k);
  
 const V& get(const K& key) const;
  V* get_ptr(const K& key);
  void set(const K& key, const V& v);
  vector<K> keys() const;
  vector<V> get_values() const;
};

template <class K, class V>
inline
size_t DictMap<K, V>::size() const 
{ 
  return this->map<K,V>::size(); 
}

template <class K, class V>
inline
bool DictMap<K, V>::has_key(const K& k) const 
{
  return this->find(k) != this->end();
}

template <class K, class V>
inline
void DictMap<K, V>::remove(const K& k) 
{
  this->erase(k);
}
  
template <class K, class V>
inline
const V& DictMap<K, V>::get(const K& key) const 
{
  typename map<K, V>::const_iterator it = this->find(key);
  if (it == this->end()) {
    ostringstream msg;
    msg << "Dict::get const: no such key " << key;
    throw Error(__FILE__, __LINE__, msg.str());
  }
  return (*it).second;
}

template <class K, class V>
inline
V* DictMap<K, V>::get_ptr(const K& key) 
{
  typename map<K, V>::iterator it = this->find(key);
  if (it == this->end()) {
    ostringstream msg;
    msg << "Dict::get_ptr: no such key " << key;
    throw Error(__FILE__, __LINE__, msg.str());
  }
  return &(*it).second;
}

template <class K, class V>
inline
void DictMap<K, V>::set(const K& key, const V& v) 
{ 
  this->insert(make_pair(key, v));
}

template <class K, class V>
inline
vector<K> DictMap<K, V>::keys() const {
  vector<K> ret;
  for (typename map<K, V>::const_iterator it = this->begin(); 
       it != this->end(); 
       ++it) {
    ret.push_back((*it).first);
  }
  return ret;
}

template <class K, class V>
inline
vector<V> DictMap<K, V>::get_values() const 
{
  vector<V> ret;
  for (typename map<K, V>::const_iterator it = this->begin(); 
       it != this->end(); 
       ++it) {
    ret.push_back((*it).second);
  }
  return ret;
}


#if 0
template <typename K, typename V>
class DictSortedVector
{
public:
  typedef vector<pair<K, V> > vs_t;

  size_t size() const;
  V* get_ptr_at(size_t key_index);  
  const V& get_at(size_t key_index) const;
  const K& key_at(size_t key_index) const;
  bool find(const K& key, size_t* key_index) const;
  void set(const K& key, const V& value);  
  void remove_at(size_t key_index);

 private:
    vs_t vs;
};
#endif

#endif
